# -*- coding: utf8 -*-
import json
import base64
from docx import Document
from openpyxl import load_workbook
import hashlib
import requests
import os
import zipfile
import re
import traceback
import logging
import random
logger = logging.getLogger()
logger.setLevel(logging.INFO)

class word:
    def __init__(self,filepath):
        self.document = Document(filepath)

    def margin(self, params):
        #print('判断页边距')
        return eval('round(self.document.sections[0].{0}_margin.mm, 1)'.format(params['DL']))

    def orientation(self, params):
        #print('页面方向', self.document.sections[0].orientation)
        return self.document.sections[0].orientation

    def page_height(self, params):
        #print('纸张高度', round(self.document.sections[0].page_height.mm))
        return round(self.document.sections[0].page_height.mm)

    def page_width(self, params):
        #print('纸张宽度', round(self.document.sections[0].page_width.mm))
        return round(self.document.sections[0].page_width.mm)

    def Header(self, params):
        paragraphs = self.document.sections[0].header.paragraphs
        text = []
        for paragraph in paragraphs:
            a = paragraph.text
            if a == '':
                if paragraph.part.element.xml.find('<w:instrText xml:space="preserve"> PAGE  \* MERGEFORMAT </w:instrText>') != -1:
                    a = 'pageNum'
            text.append(a)
        text = '\n'.join(text)
        #print('页眉', text)
        return text

    def Footer(self, params):
        paragraphs = self.document.sections[0].footer.paragraphs
        text = []
        for paragraph in paragraphs:
            a = paragraph.text
            if a == '':
                if paragraph.part.element.xml.find('PAGE  \* MERGEFORMAT') != -1:
                    a = 'pageNum'
            text.append(a)
        text = '\n'.join(text)
        #print('页脚', text)
        return text

    def keyword(self, params):  # 查找关键字，用于文档合并和查找替换两个考点，返回找到的关键词数量

        #print('关键字')
        count = 0
        if 'DL' not in set(params):  # 是否指定段落

            paragraphs = self.document.paragraphs
            for paragraph in paragraphs:
                count += paragraph.text.count(params['keyword'])
        else:
            #print('找到段落标记', params['DL'])
            paragraph = self.document.paragraphs[int(params['DL'])]
            count += paragraph.text.count(params['keyword'])
            print(paragraph.text)
        #print('找到关键词{}个'.format(count))
        return count

    def modifyPassword(self, params):
        #print('限制编辑密码', self.document.settings.element.xml.find('w:writeProtection') != -1)
        return (self.document.settings.element.xml.find('w:writeProtection') != -1)

    def paragraphStyle(self, params):
        return eval('self.document.paragraphs[{0}].paragraph_format.{1}'.format(params['DL'], params['type']))

    def wordStyle(self, params):
        #print('字体样式')
        if 'DL' in set(params):
            a = eval('self.document.paragraphs[{0}]'.format(params['DL']))
            a = a.runs
        else:
            a = []
            for paragraph in self.document.paragraphs:
                for run in paragraph.runs:
                    a.append(run)
                    #logger.info(run.text)
            #a = 
        if 'keyword' in set(params):
            for run in a:
                #print(run.text)
                if params['keyword'] in run.text:
                   # logger.error('找到关键词',  eval('run.{0}'.format(params['type'])))
                    return eval('run.{0}'.format(params['type']))
        else:
            #print(eval('a.runs[0].{0}'.format(params['type'])))
            return eval('a[0].{0}'.format(params['type']))
        return ''
    
    def keywordxml(self, params):
        a = self.document.element.xml
        a = re.sub(r'\s', '', a)
        keyword = params['keyword']
        keyword = re.sub(r'\\\\d\+', '\d+', str(keyword))
        #logger.info('关键词：' + keyword)
        pattern_ = re.compile(keyword, flags=re.X)
        #  print(a.count(params['keyword']))
        
        a = pattern_.findall(a)
        return len(a)

    def table(self, params):
        #  print(eval('self.document.tables[{0}].{1}'.format(params['DL'], params['type'])))
        return eval('self.document.tables[{0}].{1}'.format(params['DL'], params['type']))



class excel():
    def __init__(self, path):
        self.excel = load_workbook(path)

    def sheetname(self, paarams):
        #print(self.excel.sheetnames)
        return self.excel.sheetnames

    def mergeCells(self, params):
        cells = eval('self.excel.active["{0}":"{1}"]'.format(params['cell_s'], params['cell_e']))[0]
        for cell in cells:  # 检查单元格是否合并，如果从第二个单元格开始类型部署mergedcell则没合并
            if str(type(cell)) == "<class 'openpyxl.cell.cell.Cell'>" and cell != cells[0]:
                return ''
        #  如果正确的话返回单元格值
        return cells[0].value

    def cell(self, params):  # 单元格属性
        #print(eval('self.excel.active["{0}"].{1}'.format(params['cell'], params['type'])))
        return eval('self.excel.active["{0}"].{1}'.format(params['cell'], params['type']))

    def cells(self, params):  # 单元格文本集合，用于判断外部数据导入
        rows = eval('self.excel.active["{0}":"{1}"]'.format(params['cell_s'], params['cell_e']))
        fulltext = ''
        for cells in rows:
            for cell in cells:
                a = str(eval('str(cell.{0})'.format(params['type'])))
                if a != 'None' :
                    fulltext += a
        #fulltext = str(fulltext[:-1])
        print(fulltext)
        fulltextmd5 = hashlib.md5(fulltext.encode('utf-8')).hexdigest()
        return fulltextmd5

    def cellheight(self, params):
        a = int(params['cell_s'])
        full = ''
        while a < int(params['cell_e']):
            full += str(self.excel.active.row_dimensions[a].height)
            a += 1
        fulltextmd5 = hashlib.md5(full.encode('utf-8')).hexdigest()
        return fulltextmd5

    def cellwidth(self, params):
        #  s = list('ABCDEFGHIJKLMNOPQRST')
        full = ''
        for col in self.excel.active.column_dimensions:
            full += str(self.excel.active.column_dimensions[col].width)
        fulltextmd5 = hashlib.md5(full.encode('utf-8')).hexdigest()
        print(full)
        return fulltextmd5

    def table(self, params):
        try:
            return eval('self.excel.active._charts[{0}].ser[0].val.numRef.f'.format(params['index']))
        except:
            return ''

class python():
    def __init__(self, filepath):
        with open(filepath, 'r') as f:
            self.text = f.read()
            self.text = self.text.replace("'", '"')
    
    def keyword(self, params):
        params['keyword'] = params['keyword'].replace("'", '"')
        return self.text.count(params['keyword'])

class windows():
    def __init__(self, path):
        """unzip zip file"""
        zip_file = zipfile.ZipFile(path)
        os.mkdir(path + "_files")
        zip_file.extractall(path + "_files/")
        zip_file.close()
        self.dir = path + "_files/"
        logger.info('文件列表')
        logger.info(os.listdir(self.dir))

    def existDir(self, params):
        try:
            return os.path.isdir(self.dir + params['path'])
        except:
            return 'False'

    def attribute(self, params):
        with open(self.dir + 'read', 'r') as f:
            text = f.read()
            if text.find(params['path']) == -1:
                return ''
            else:
                return 'readonly'
        #  return statinfo.st_file_attributes

    def existFile(self, params):
        return os.path.isfile(self.dir + params['path'])

    def rar(self, params):
        zipFile = zipfile.ZipFile(self.dir + params['path'])
        try:
            savepath = '/tmp/' + str(random.randint(100000001,99999999999)) + '_file/'
            os.mkdir(savepath)
            logger.info('文件夹创建成功')
            zipFile.extractall(path=savepath, pwd=str(params['password']).encode('utf-8'))
            if (len(os.listdir(savepath)) == 0):
                logger.info('压缩文件无内容')
                return False
            else:
                return True
        except:
            logger.info('抛出异常', traceback.print_exc())
            return False

class foxmail():
    def __init__(self, path):
        """unzip zip file"""
        zip_file = zipfile.ZipFile(path)
        os.mkdir(path + "_files")
        zip_file.extractall(path + "_files/")
        zip_file.close()
        dir = path + "_files/"
        with open("1.json",'r') as f:
            self.text = base64.b64decode(f.read().encode('utf-8'))
    
    def keyword(self, params):

        return self.text.count(params['keyword'])



def main_handler(event, context):

    uid = event['headers']['uid']
    timestamp = event['headers']['timestamp']
    authorization = event['headers']['authorization']
    headers = {
        'uid': uid,
        'timestamp': timestamp,
        'authorization': authorization
    }
    result = requests.get('https://api.eduxcyun.com/v2/exam/officecode?questionid=' + event['headers']['questionid'], headers=headers)
    result = json.loads(result.text)
    if result['code'] != '200':
        return result
    contents = base64.b64decode(str(result['data']['answer']).encode('utf-8')).decode('utf-8')
    contents = json.loads(contents)
    #return contents
    sortid = str(result['data']['type'])
    if sortid == '6':
        type = 'docx'
    elif sortid == '7':
        type = 'xlsx'
    elif sortid == '11':
        type = 'py'
    elif sortid == '9' or sortid == '11':
        type = 'zip'
    filepath = '/tmp/' + str(uid) + '_' + str(timestamp) + '_' + str(event['headers']['questionid']) +'.' + type
    with open(filepath, 'wb') as f:
        f.write(base64.b64decode(event['body']))
    if sortid == '6':
        data_ = word(filepath)
    elif sortid == '7':
        data_ = excel(filepath)
    elif sortid == '11':
        data_ = python(filepath)
    elif sortid == '9':
        data_ = windows(filepath)
    elif sortid == '11':
        data_ = foxmail(filepath)
    score = 0
    err = ''
    for content in contents:
        command = 'data_.{0}({1})'.format(content['key'], content['params'])
        
        try:
            source = str(eval(command))
            #source = re.sub(r'\s','',source)
        except: 
            source = '喵~执行错误'
            logger.info('command：' + command)
        des = str(content['value'])
        if source == des:
            score += float(content['score'])
        else:
            
            logger.info('用户ID/时间戳：' + uid + ' / ' + timestamp)
            
            logger.info('文件值：' + source)
            logger.info('期望值：' + des)
            err += str(content['msg'] + '<br />')

    return {'score': score, 'err': err, 'requestid': event['headers']['x-api-requestid']}
